<template>
  <div class="task common-layout">
    <el-container class="container-box">
      <el-container class="container-content">
        <el-header class="container-header">
          <el-radio-group v-model="sort">
            <el-radio :value="1">按开始时间排序</el-radio>
            <el-radio :value="-1">按结束时间排序</el-radio>
            <el-button @click="start" size="default" type="primary"
              >刷新</el-button
            >
            <router-link
              v-slot="{ navigate }"
              custom
              :to="{ name: '创建任务', params: { ID: teamId } }"
            >
              <el-button size="default" type="primary" @click="navigate">
                创建任务
              </el-button>
            </router-link>
          </el-radio-group>
        </el-header>
        <el-main class="container-main" v-loading="taskLoading">
          <el-scrollbar>
            <el-table
              height="80vh"
              :data="taskData"
              style="width: 100%"
              @row-click="showTaskRank"
              :row-class-name="rowClassName"
            >
              <template v-slot:empty>
                <el-empty
                  image="https://cdn-hterobot.oss-cn-qingdao.aliyuncs.com/image/ojSass-empty.png"
                />
              </template>
              <el-table-column type="expand">
                <template #default="{ row }">
                  <el-descriptions
                    class="container-content-cardDescriptions"
                    :column="2"
                  >
                    <el-descriptions-item :span="2" label="任务完成条件：">
                      {{
                        taskTypeInfoCfg[row.type || "question"].conditionText(
                          row.questionnum || 0,
                          row.questionac
                        )
                      }}
                    </el-descriptions-item>
                    <el-descriptions-item :span="2" label="我的进度：">
                      <span style="display: inline-block; width: 45%">
                        <el-progress :percentage="myTaskInfo(row).num" />
                      </span>
                    </el-descriptions-item>
                    <el-descriptions-item
                      v-show="row.reward"
                      :span="2"
                      label="任务奖励："
                    >
                      {{ row.reward }}
                    </el-descriptions-item>
                    <el-descriptions-item
                      v-show="row.remarks"
                      :span="2"
                      label="备注："
                    >
                      {{ row.remarks }}
                    </el-descriptions-item>
                  </el-descriptions>
                </template>
              </el-table-column>
              <el-table-column
                prop="name"
                label="任务"
                width=""
              ></el-table-column>
              <el-table-column prop="" label="类型" width="">
                <template #default="{ row }">
                  {{ taskTypeInfoCfg[row.type || "question"].title }}
                </template>
              </el-table-column>
              <el-table-column prop="date" label="开始时间" width="">
                <template #default="{ row }">
                  {{ dayjs(row.starttime).format("YYYY-MM-DD") }}
                </template>
              </el-table-column>
              <el-table-column prop="date" label="结束时间" width="">
                <template #default="{ row }">
                  {{ dayjs(row.endtime).format("YYYY-MM-DD") }}
                </template>
              </el-table-column>
              <el-table-column prop="date" label="创建时间" width="">
                <template #default="{ row }">
                  {{ TimeYH(row.createdAt) }}
                </template>
              </el-table-column>
              <el-table-column prop="date" label="状态" width="">
                <template #default="{ row }">
                  {{ checkTaskStatus(row).title }}
                </template>
              </el-table-column>
              <el-table-column prop="date" label="完成人数" width="">
                <template #default="{ row }">
                  {{
                    getFinishUser(row.ID, row.questionnum, taskFinishInfo)
                      .length || 0
                  }}
                </template>
              </el-table-column>
              <el-table-column prop="date" label="操作" width="250">
                <template #default="{ row }">
                  <router-link
                    v-slot="{ navigate }"
                    custom
                    :to="{
                      name: '创建任务',
                      params: { ID: teamId },
                      query: { ID: row.ID },
                    }"
                  >
                    <el-button
                      @click.stop="navigate"
                      type="primary"
                      size="default"
                      >修改</el-button
                    >
                  </router-link>
                  <el-button
                    @click.stop="del(row.ID)"
                    type="danger"
                    size="default"
                    >删除</el-button
                  >
                  <el-button
                    size="default"
                    type="info"
                    @click.stop="copyTask(row.ID)"
                    >复制</el-button
                  >
                </template>
              </el-table-column>
            </el-table>
            <!-- 分页 -->
            <el-pagination
              class="pager"
              :page-size="limit"
              :total="totalCount"
              @current-change="changePage"
              layout="total,prev, pager, next"
              :current-page="Math.floor(offset / limit) + 1"
            >
            </el-pagination>
          </el-scrollbar>
        </el-main>
      </el-container>
      <el-aside
        class="container-right"
        v-loading="taskDetailLoading"
        :collapsible="isCollapse"
        :width="isCollapse ? '1px' : '28%'"
      >
        <el-scrollbar>
          <el-menu :collapse="isCollapse">
            <div class="">
              <el-descriptions
                class="container-right-header"
                :title="selectedTask.name"
                :column="2"
                size="default"
              >
                <template #title>
                  <div class="text-title">
                    <b
                      >{{ selectedTask.name }}-{{
                        checkTaskStatus(selectedTask).title
                      }}</b
                    >
                  </div>
                </template>
                <template #extra>
                  <el-button
                    @click="isCollapse = true"
                    size="default"
                    type="info"
                    text
                  >
                    <el-icon>
                      <Close />
                    </el-icon>
                    关闭侧栏
                  </el-button>
                </template>
                <el-descriptions-item :span="2" label="类型:">
                  {{ taskTypeInfoCfg[selectedTask.type || "question"].title }}
                </el-descriptions-item>
                <el-descriptions-item :span="2" label="完成条件:">
                  {{
                    taskTypeInfoCfg[
                      selectedTask.type || "question"
                    ].conditionText(
                      selectedTask.questionnum || 0,
                      selectedTask.questionac
                    )
                  }}
                </el-descriptions-item>
                <!-- <el-descriptions-item :span="1" label="任务状态:">
                                    {{ checkTaskStatus(selectedTask).title }}
                                </el-descriptions-item> -->
                <el-descriptions-item :span="1" class="text-right">
                  <el-button @click="exportExcel" size="default" type="primary"
                    >导出</el-button
                  >
                  <!-- <el-button @click="isCollapse = true" size="default" type="primary">关闭侧栏</el-button> -->
                </el-descriptions-item>
              </el-descriptions>
              <el-table
                height="70vh"
                row-class-name="cursor-pointer"
                :data="memberTaskRank"
                @row-click="showMemberFinishDetail"
              >
                <template v-slot:empty>
                  <el-empty
                    image="https://cdn-hterobot.oss-cn-qingdao.aliyuncs.com/image/ojSass-empty.png"
                  />
                </template>
                <!-- <el-table-column label="" type="index" width="80"></el-table-column> -->
                <el-table-column prop="name" label="成员"></el-table-column>
                <el-table-column
                  prop="finishCount"
                  label="完成数"
                  width="80"
                ></el-table-column>
                <el-table-column prop="finishCount" label="完成进度">
                  <template #default="{ row }">
                    <el-progress
                      :text-inside="true"
                      :stroke-width="18"
                      :percentage="row.percent"
                      :color="customColors"
                    />
                  </template>
                </el-table-column>
                <el-table-column prop="finishDate" label="完成时间">
                  <template #default="{ row }">
                    {{ row.percent >= 100 ? TimeYH1(row.finishDate) : "-" }}
                  </template>
                </el-table-column>
              </el-table>
            </div>
          </el-menu>
        </el-scrollbar>
      </el-aside>
      <!-- 查看成员任务完成情况弹窗 -->
      <el-dialog v-model="memberTaskDetaildialogVisible">
        <template #header>
          <span class="icon-text el-dialog__header-title">
            <el-icon class="text-primary">
              <Guide />
            </el-icon>
            {{ `${selectedMember.name}-任务详情` }}
          </span>
        </template>
        <QuestionFinishDetail
          v-if="taskType === TaskType.QUESTION"
          :selectedTask="selectedTask"
          :selectedMember="selectedMember"
          :teamjobrelation="questionTaskRelation"
        >
        </QuestionFinishDetail>
        <VideoFinishDetail
          v-else-if="taskType === TaskType.VIDEO"
          :selectedTask="selectedTask"
          :selectedMember="selectedMember"
          :teamjobrelation="videoTaskRelation"
        >
        </VideoFinishDetail>
        <FileFinishDetail
          v-else="taskType === TaskType.FILE"
          :selectedTask="selectedTask"
          :selectedMember="selectedMember"
          :teamjobrelation="fileTaskRelation"
        >
        </FileFinishDetail>
      </el-dialog>
    </el-container>
  </div>
</template>

<script setup lang="ts">
import dayjs from "dayjs";
import { ElMessage, ElMessageBox } from "element-plus";
import moment from "moment";
import { computed, onMounted, ref, watch } from "vue";
import { useStore } from "vuex";
import {
  asyncTeamCopyTeamJob,
  asyncselectteamjobrelation,
  asyncselectteamjobrelations,
  asyncselectteamselectuser,
  asyncteamdelteamjob,
  asyncteamselectteamjob,
} from "../../../api";
import { Storekey } from "../../../interface";
import Alymodel from "../../../mysql_interface/model";
import Studycodemodel from "../../../mysql_interface/studycodemodel";
import { getExceltodownload } from "../../../util/excel";
import { TimeYH, TimeYH1 } from "../../../util/time";
import FileFinishDetail from "./fileFinishDetail.vue";
import QuestionFinishDetail from "./questionFinishDetail.vue";
import { MemberFinishTaskDetail, TaskType } from "@/util/type";
import VideoFinishDetail from "./videoFinishDetail.vue";

const customColors = [
  { color: "#e83828", percentage: 20 },
  { color: "#f0830ac", percentage: 40 },
  { color: "#82bd1c", percentage: 60 },
  { color: "#1ecbb4", percentage: 70 },
  { color: "#4683fa", percentage: 100 },
];

const taskTypeInfoCfg: Record<
  TaskType,
  { title: string; conditionText: (num: number, degree?: number) => string }
> = {
  video: {
    title: "观看视频",
    conditionText: (num: number, degree?: number) =>
      `观看${num}节课程视频, 且观看视频时长大于${degree}`,
  },
  question: {
    title: "题目练习",
    conditionText: (num: number, degree?: number) =>
      `完成${num}题, 且代码题目测试点正确率${degree}%`,
  },
  file: {
    title: "学习资料",
    conditionText: (num: number, degree?: number) => `学习${num}份资料`,
  },
};
const TaskStatusCfg: {
  [key: number]: {
    title: string;
    type: "primary" | "success" | "info" | "warning" | "danger";
    bntText: string;
    show: boolean;
    disabled: boolean;
  };
} = {
  0: {
    title: "未开始",
    type: "warning",
    bntText: "任务没有开始",
    show: true,
    disabled: true,
  },
  1: {
    title: "已结束",
    type: "info",
    bntText: "任务已经结束",
    show: false,
    disabled: true,
  },
  2: {
    title: "进行中",
    type: "success",
    bntText: "去完成",
    show: true,
    disabled: false,
  },
};
const taskLoading = ref(true);
const store = useStore(Storekey);
// 当前登录用户
const user = computed(() => {
  return store.state.user;
});
const teamId = computed(() => {
  return user.value?.teamid;
});

const sort = ref(-1);
watch(sort, async (e) => {
  // 获取最新的排序方式
  await getTeamTask();
  // tableDataSort()
});

const teamUsers = ref<Studycodemodel.Iteamuser[]>([]);
// 任务完成情况 userid: 100007, teamjobid: 11048, state: true, count: 2
const taskFinishInfo = ref<Studycodemodel.Iteamjobrelation[]>([]);
// 根据任务id,任务目标数 获取已完成成员
function getFinishUser(
  taskId: number,
  count: number,
  taskFinisUser: Studycodemodel.Iteamjobrelation[]
) {
  const ret: Studycodemodel.Iteamjobrelation[] = [];
  taskFinisUser.forEach((e) => {
    if (e.teamjobid === taskId && e.count >= count) {
      // 补充name
      const user = teamUsers.value.find((u) => u.userid === e.userid) || {};
      ret.push({ ...e, name: user?.user?.name || "" });
    }
  });
  return ret;
}
// 我的任务完成情况
function myTaskInfo(row: Studycodemodel.Iteamjob) {
  const questionnum = row.questionnum || 1;
  const n = row.teamjobrelation?.filter((e) => e.userid === user.value?.ID);
  if (n?.length) {
    const _n = n.filter((e) => !e.state);
    const num = Math.floor(
      (n.filter((e) => e.state).length / questionnum) * 100
    );
    return {
      isshow: true,
      num: num > 100 ? 100 : num,
      next: _n,
    };
  }
  return {
    isshow: false,
    num: 0,
  };
}

onMounted(async () => {
  await start();
  // tableDataSort()
  // 右侧默认显示
  // showTaskRank(taskData.value[0])
});
// 查询条件
const offset = ref<number>(0);
const limit = ref<number>(20);
// 具体任务
const questions = ref<Studycodemodel.Iquestion[]>([]);
const courses = ref<Alymodel.IMcourse[]>([]);
const teamFiles = ref<Studycodemodel.Iteamfile[]>([]);
const taskData = ref<Studycodemodel.Iteamjob[]>([]);
const totalCount = ref<number>(0);
async function start() {
  taskLoading.value = true;
  // 任务列表
  await getTeamTask();
  // 团队成员
  teamUsers.value = await asyncselectteamselectuser({ teamid: teamId.value });
  // 完成情况
  const taskID = taskData.value.map((e) => e.ID);
  const ret = await asyncselectteamjobrelations({
    _order: "teamjobid",
    teamid: teamId.value,
    teamjobid: taskID,
    state: true,
  });
  taskFinishInfo.value = ret;
  taskLoading.value = false;
}
async function getTeamTask() {
  let order = ["ID"];
  if (sort.value > 0) {
    order = ["starttime", "ID"];
  } else {
    order = ["endtime", "ID"];
  }
  // 任务列表
  const { rows, count, question, course, teamfile } =
    await asyncteamselectteamjob({
      _offset: offset.value,
      _limit: limit.value,
      teamid: teamId.value,
      _order: order,
      _sortable: "DESC",
    });
  questions.value = question.map((e) => {
    return { ID: e.ID, name: e.name, label: e.label };
  });
  courses.value = course.map((e) => {
    return { ID: e.ID, name: e.name };
  });
  teamFiles.value = teamfile.map((e) => {
    return { ID: e.ID, name: e.name, size: e.size, url: e.url };
  });
  taskData.value = rows;
  totalCount.value = count;
}
// formatter
function checkTaskStatus(data: Studycodemodel.Iteamjob) {
  const { starttime, endtime } = data;
  const n = dayjs().unix();
  if (n < dayjs(starttime).unix()) {
    return TaskStatusCfg[0];
  }
  if (n > dayjs(endtime).unix()) {
    return TaskStatusCfg[1];
  }
  return TaskStatusCfg[2];
}
function changePage(r: number) {
  offset.value = (r - 1) * limit.value;
  getTeamTask();
}

function tableDataSort() {
  taskData.value.sort((a, b) => {
    let diff = 0;
    // 倒序
    if (sort.value > 0) {
      diff = new Date(b.starttime).getTime() - new Date(a.starttime).getTime();
    } else {
      diff = new Date(b.endtime).getTime() - new Date(a.endtime).getTime();
    }
    return diff;
  });
}

// 右侧aside展开详情
const width = ref("0");
const isCollapse = ref(true);
const taskDetailLoading = ref(false);
const selectedTask = ref<Studycodemodel.Iteamjob>({});
const taskType = computed(() => {
  return selectedTask.value.type || TaskType.QUESTION;
});
// userid,state,updatedAt,questionid,teamfileid,,watchvideoid
const teamTaskRelation = ref<Studycodemodel.Iteamjobrelation[]>([]);
// 展开aside
async function showTaskRank(teamTask: Studycodemodel.Iteamjob) {
  taskDetailLoading.value = true;
  selectedTask.value = teamTask;
  const { rows } = await asyncselectteamjobrelation({
    teamid: teamId.value,
    teamjobid: teamTask.ID,
    _limit: 999999,
  });
  teamTaskRelation.value = rows;
  isCollapse.value = false;
  width.value = "50%";
  taskDetailLoading.value = false;
}
function rowClassName({
  row,
  rowIndex,
}: {
  row: Studycodemodel.Iteamjob;
  rowIndex: number;
}): string {
  let className = "cursor-pointer";
  if (selectedTask.value == row) {
    className = "highlight-row cursor-pointer"; //
  }
  return className;
}

// 成员任务完成情况 aside-table
const memberTaskRank = computed(() => {
  let users = new Map<number, MemberFinishTaskDetail>();
  // 初始化所有成员的完成情况
  // teamUsers.value.forEach(e => {
  //     let tmp = users.get(e.userid)
  //     if (!tmp) {
  //         users.set(e.userid, {
  //             taskType: selectedTask.value.type,
  //             taskId: selectedTask.value.ID,
  //             userId: e.userid, name: e.user?.name, finishCount: 0, percent: 0, finishDate: undefined
  //         })
  //     }
  // })
  teamTaskRelation.value.forEach((e) => {
    let tmp = users.get(e.userid);

    if (!tmp) {
      users.set(e?.userid, {
        taskType: selectedTask.value.type,
        taskId: selectedTask.value.ID,
        userId: e.userid,
        name:
          teamUsers.value.find((u) => u.userid === e.userid)?.user?.name ||
          e.userid,
        finishCount: e.state ? 1 : 0,
        totalCount: selectedTask.value.questionnum,
        percent: 0,
        finishDate: undefined,
      });
    }

    if (e.state && tmp) {
      tmp.finishCount += 1;
      if (tmp.finishDate) {
        let isAfter = moment(e.updatedAt).isAfter(tmp.finishDate);
        tmp.finishDate = isAfter ? e.updatedAt! : tmp.finishDate;
      } else {
        tmp.finishDate = e.updatedAt!;
      }
      let percent = selectedTask.value.questionnum
        ? parseInt((tmp.finishCount / selectedTask.value.questionnum) * 100)
        : 0;
      tmp.percent = percent > 100 ? 100 : percent;
    }
  });
  return Array.from(users.values())
    .sort((a, b) => {
      return (
        (b.finishDate ? new Date(b.finishDate).getTime() : 0) -
        (a.finishDate ? new Date(a.finishDate).getTime() : 0)
      );
    })
    .sort((a, b) => b.percent - a.percent);
});
// 导出
function exportExcel() {
  const data = [["成员", "完成进度", "完成时间"]];
  for (let v of memberTaskRank.value.filter((e) => e.finishCount)) {
    const n = [
      v?.name || "",
      v.percent + "%",
      v.percent >= 100 ? new Date(v.finishDate).toLocaleString() : "",
    ];
    data.push(n);
  }
  getExceltodownload(data, String(selectedTask.value.name));
}

// 某个任务某个成员的具体完成情况
const selectedMember = ref<MemberFinishTaskDetail>({}); // 概况
const memberTaskRelation = ref<Studycodemodel.Iteamjobrelation[]>([]); // 详情
const questionTaskRelation = ref<Studycodemodel.Iteamjobrelation[]>([]); // question
const videoTaskRelation = ref<Studycodemodel.Iteamjobrelation[]>([]); // video
const fileTaskRelation = ref<Studycodemodel.Iteamjobrelation[]>([]); // file
const memberTaskDetaildialogVisible = ref(false);
function showMemberFinishDetail(row: MemberFinishTaskDetail) {
  selectedMember.value = row;
  memberTaskDetaildialogVisible.value = true;
  const selectedUid = row.userId;
  // 从 selectteamjobrelation 筛选指定成员
  memberTaskRelation.value = teamTaskRelation.value.filter(
    (e) => e.userid === selectedUid
  );
  if (taskType.value === TaskType.QUESTION) {
    // 补全任务中的题目名称
    questionTaskRelation.value = memberTaskRelation.value.map((f) => {
      const q = questions.value.find((t) => t.ID === f.questionid);
      return { ...f, qName: q.name };
    });
  } else if (taskType.value === TaskType.VIDEO) {
    videoTaskRelation.value =
      memberTaskRelation.value.map((f) => {
        const { courseid, watchvideoid, catebagid, state } = f;
        // 所有资源中筛选本任务的
        const course = courses.value.find((t) => t.ID === courseid);
        return {
          courseid,
          name: course?.name,
          time:
            watchvideoid
              ?.map((f) => f.time)
              .reduce((a = 0, b = 0) => a + b, 0) || 0,
          catebagid,
          state,
        };
      }) || [];
  } else if (taskType.value === TaskType.FILE) {
    fileTaskRelation.value =
      memberTaskRelation.value.map((f) => {
        const { teamfileid, state } = f;
        const course = teamFiles.value.find((t) => t.ID === teamfileid);
        return {
          teamfileid,
          name: course?.name,
          state,
        };
      }) || [];
  }
}

//
function del(ID?: number) {
  ElMessageBox.confirm("确定要删除该任务？", "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(() => {
    asyncteamdelteamjob({ ID, teamid: teamId.value })
      .then(() => {
        ElMessage.success("删除成功");
        start();
      })
      .catch(() => {
        ElMessage.info("删除失败");
      });
  });
}

// copyTask
function copyTask(ID?: number) {
  if (ID) {
    try {
      ElMessageBox.confirm("是否复制该任务, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(async () => {
          await asyncTeamCopyTeamJob({ ID, teamid: teamId.value! });
          ElMessage({
            type: "success",
            message: "复制成功!",
          });
          start();
        })
        .catch((e) => {
          console.error("err:", e);
          ElMessage({
            type: "info",
            message: "已取消复制",
          });
        });
    } catch (e: any) {
      ElMessage({
        message: "复制失败" + e,
        type: "error",
      });
    }
  }
}
</script>

<style scoped>
.container-box {
  /* 外边距 */
  --container-margin: 20px;
  --container-header-height: 7vh;
  --container-bg-color: #fff;
}

.container-header {
  height: auto;
  background: var(--container-bg-color);
  width: 100%;
}

.container-content {
  margin-right: var(--container-margin);
  background: var(--container-bg-color);
  min-width: 65%;
}

.container-main {
  margin-top: var(--container-margin);
  padding: 0;
}

/* 控制高度 不用整个页面都有滚动条 方便查看右侧详情 */
/* nav header height 48px */
.container-right {
  max-height: calc(100vh - 48px - 2 * var(--container-margin));
}

.container-content {
  max-height: calc(100vh - 48px - 2 * var(--container-margin));
}

.container-content-cardBox {
  display: flex;
  flex-wrap: wrap;
  padding-right: 10px;
  /* 没有margin-top 任务状态的定位标签会被el-scroll overflow:hidden */
  /* margin-top: 15px */
}

.container-content-cardItem {
  position: relative;
  margin: 12px;
  flex: 1;
}

/* 任务状态标签tag */
.container-content-cardItemTag {
  margin-left: 10px;
}

.container-content-cardItemDetail {
  top: 4%;
  right: 3%;
  position: absolute;
}

.container-content-cardDescriptions {
  min-width: 30vw;
  padding: 20px;
}

.container-content-cardFinishTag {
  display: inline-block;
  margin: 0.1rem 0.1rem 0;
}

.container-right {
  /* padding: var(--container-margin); */
  padding-right: 0;
  background: var(--container-bg-color);
}

.container-right-header {
  padding: 0 20px;
}
</style>

<style>
.task .container-right .el-menu {
  border: none;
}

.task .el-overlay-dialog {
  position: fixed !important;
}
</style>
